package com.example.user.adapter.in.web.service;

import com.example.user.service.common.JwtUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Service
@RequiredArgsConstructor
public class TokenBlacklistService {
    private final JwtUtils jwtUtil;

    private final ConcurrentHashMap<String, Date> blacklistedTokens = new ConcurrentHashMap<>();

    public void addToBlacklist(String token) {
        try {
            Date expirationTime = jwtUtil.getExpirationDateFromToken(token);
            blacklistedTokens.put(token, expirationTime);
            log.info("令牌已添加到黑名单，过期时间: {}, 令牌前缀: {}...", 
                    expirationTime, 
                    token.substring(0, Math.min(token.length(), 10)));
                    
        } catch (Exception e) {
            log.warn("添加令牌到黑名单时发生错误: {}, 令牌前缀: {}...", 
                    e.getMessage(), 
                    token.substring(0, Math.min(token.length(), 10)));
        }
    }


    public boolean isBlacklisted(String token) {
        boolean isBlacklisted = blacklistedTokens.containsKey(token);
        
        if (isBlacklisted) {
            log.debug("检测到黑名单令牌访问尝试，令牌前缀: {}...", 
                    token.substring(0, Math.min(token.length(), 10)));
        }
        
        return isBlacklisted;
    }

    @Scheduled(fixedRate = 3600000) // 每小时执行一次
    public void cleanupExpiredTokens() {
        Date now = new Date();
        int initialSize = blacklistedTokens.size();

        blacklistedTokens.entrySet().removeIf(entry -> {
            Date expirationTime = entry.getValue();
            return expirationTime != null && now.after(expirationTime);
        });
        
        int finalSize = blacklistedTokens.size();
        int cleanedCount = initialSize - finalSize;
        
        if (cleanedCount > 0) {
            log.info("黑名单清理完成，清理了 {} 个过期令牌，当前黑名单大小: {}", cleanedCount, finalSize);
        } else {
            log.debug("黑名单清理完成，无过期令牌需要清理，当前黑名单大小: {}", finalSize);
        }
    }

    public int getBlacklistSize() {
        return blacklistedTokens.size();
    }

    public void clearBlacklist() {
        int size = blacklistedTokens.size();
        blacklistedTokens.clear();
        log.warn("黑名单已被清空，共清理了 {} 个令牌", size);
    }
}